import json
import re

from celery import current_app
from django import http
from django.contrib.auth import login, authenticate, logout
from django.shortcuts import render, redirect
from django.urls import reverse
from django.views import View
from django_redis import get_redis_connection
from pymysql import DatabaseError

from apps.boke_content.models import Category, Image, Blog
from apps.users.models import User
from libs.qiniuyun.code import storage
from utils.response_code import RETCODE
from utils.views import LoginRequiredJSONMixin


class RegisterView(View):
    def get(self, request):
        return render(request, 'register.html')

    def post(self, request):
        username = request.POST.get('username')
        email = request.POST.get('email')
        password = request.POST.get('password')
        password2 = request.POST.get('password2')
        img_code = request.POST.get('code')
        uuid = request.POST.get('uuid')

        # 判断参数是否齐全
        if not all([username, password, password2, email, img_code, uuid]):
            return http.JsonResponse({'code_s': RETCODE.NECESSARYPARAMERR, 'errmsg': '参数不足'})
        if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email):
            return http.JsonResponse({'code_s': RETCODE.EMAILERR, 'errmsg': '邮箱错误'})
        # 判断用户名是否是5-20个字符
        if not re.match(r'^[a-zA-Z0-9_]{5,20}$', username):
            return http.JsonResponse({'code_s': RETCODE.USERERR, 'errmsg': '请输入5-20位字符的用户名'})
        # 判断密码是否是8-20个数字
        if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
            return http.JsonResponse({'code_s': RETCODE.PWDERR, 'errmsg': '请输入8-20位的密码'})
        # 判断两次密码是否一致
        if password != password2:
            return http.JsonResponse({'code_s': RETCODE.CPWDERR, 'errmsg': '两次密码不一致'})

        redis_conn = get_redis_connection('code')
        image_code_server = redis_conn.get('img_%s' % uuid)
        if image_code_server is None:
            return http.JsonResponse({'code_s': RETCODE.IMAGECODEERR, 'errmsg': '验证码错误'})

        try:
            redis_conn.delete('img_%s' % img_code)
        except Exception as e:
            print(e)

        # 保存注册数据
        try:
            user = User.objects.create_user(username=username, password=password, email=email)
        except User.DoesNotExist:
            return http.JsonResponse({'code_s': RETCODE.DBERR, 'errmsg': '注册失败'})

        login(request, user)

        response = http.JsonResponse({'code_s': RETCODE.OK, 'errmsg': '注册成功'})

        response.set_cookie('username', user.username, 3600 * 24 * 15)

        return response


class LoginView(View):
    def post(self, request):
        # 接收参数
        username = request.POST.get('username')
        password = request.POST.get('password')
        img_code = request.POST.get('code')
        uuid = request.POST.get('uuid')

        # 校验参数
        # 判断参数是否齐全
        if not all([username, password, img_code, uuid]):
            return http.JsonResponse({'code_s': RETCODE.NECESSARYPARAMERR, 'errmsg': '参数不足'})

        # 判断用户名是否是5-20个字符
        if not re.match(r'^[a-zA-Z0-9_-]{5,20}$', username):
            # return http.HttpResponseBadRequest('请输入正确的用户名或手机号')
            return http.JsonResponse({'code_s': RETCODE.USERERR, 'errmsg': '请输入正确的用户名或手机号'})

        # 判断密码是否是8-20个数字
        if not re.match(r'^[0-9A-Za-z]{8,20}$', password):
            # return http.HttpResponseBadRequest('密码最少8位，最长20位')
            return http.JsonResponse({'code_s': RETCODE.PWDERR, 'errmsg': '密码最少8位，最长20位'})

        redis_conn = get_redis_connection('code')
        image_code_server = redis_conn.get('img_%s' % uuid)
        if image_code_server is None:
            return http.JsonResponse({'code': RETCODE.IMAGECODEERR, 'errmsg': '验证码错误'})

        if image_code_server.decode().lower() != img_code.lower():
            return http.JsonResponse({'code': RETCODE.IMAGECODEERR, 'errmsg': '验证码输入有误'})

        try:
            redis_conn.delete('img_%s' % img_code)
        except Exception as e:
            print(e)

        # 认证登录用户
        user = authenticate(username=username, password=password)
        if user is None:
            return http.JsonResponse({'code_s': RETCODE.PWDERR, 'errmsg': '用户名或密码错误'})

        # 实现状态保持
        login(request, user)

        response = http.JsonResponse({'code_s': RETCODE.OK, 'errmsg': '登陆成功'})

        response.set_cookie('username', user.username, 3600 * 24 * 15)

        return response


class LogoutView(View):
    def get(self, request):
        logout(request)

        # 退出登录，重定向到登录页
        response = http.JsonResponse({'code_s': RETCODE.OK, 'errmsg': '退出成功'})

        # 退出登录时清除cookie中的username
        response.delete_cookie('username')

        return response


class SendBoke(LoginRequiredJSONMixin, View):
    def get(self, request):
        category = Category.objects.all()

        context = {
            'categories': category
        }

        return render(request, 'send_news.html', context=context)

    def post(self, request):
        title = request.POST.get('title')
        category = request.POST.get('category_id')
        digest = request.POST.get('digest')
        content = request.POST.get('content')
        print(len(content))

        user = request.user

        if not user.is_authenticated:
            return http.JsonResponse({'code_s': RETCODE.SESSIONERR, 'errmsg': '未登录'})

        if not all([title, category, digest, content]):
            return http.JsonResponse({'code_s': RETCODE.NECESSARYPARAMERR, 'errmsg': '参数不足'})

        try:
            # 读取上传的文件
            file = request.FILES.get('index_image')
            avatar_file = file.read()  # 读取数据
        except Exception as e:
            return http.JsonResponse({'code_s': RETCODE.IMAGEERROR, 'errmsg': '没有图片'})
            # return jsonify(errno=RET.PARAMERR, errmsg="读取文件出错")
            # 2.保存到七牛云
        # url = storage(avatar_file)
        # image = "http://q2drs2nk4.bkt.clouddn.com/" + url
        # img = Image.objects.create(name=url, url=image)
        try:
            url = storage(avatar_file)
            image = "http://q2e9jznlm.bkt.clouddn.com/" + url
            img = Image.objects.create(name=url, url=image)
            img.save()
        except Exception as e:
            return http.JsonResponse({'code_s': RETCODE.QINIUYUNERROR, 'errmsg': '七牛云错误'})

        # Blog.objects.create(title=title, abstract=digest, category=category, content=content, image=img)
        try:
            category = Category.objects.get(id=category)
            Blog.objects.create(title=title, abstract=digest, category=category, content=content, image=img, user=user)
        except Blog.DoesNotExist:
            return http.JsonResponse({'code_s': RETCODE.DBERR, 'errmsg': '保存数据失败'})

        return http.JsonResponse({'code_s': RETCODE.OK, 'errmsg': '发布成功'})


class ChangePassword(LoginRequiredJSONMixin, View):
    def get(self, request):
        return render(request, 'password.html')

    def post(self, request):

        old_password = request.POST.get('old_password')
        new_password = request.POST.get('password')
        new_password2 = request.POST.get('password2')
        # 2.验证参数
        if not all([old_password, new_password, new_password2]):
            return http.HttpResponseForbidden('缺少必传参数')
        if not re.match(r'^[0-9A-Za-z]{8,20}$', new_password):
            return http.HttpResponseBadRequest('密码最少8位，最长20位')
        if new_password != new_password2:
            return http.HttpResponseBadRequest('两次输入的密码不一致')
        user = request.user
        # 3.检验旧密码是否正确
        if not user.check_password(old_password):
            return http.JsonResponse({'code_s': RETCODE.PWDERR, 'errmsg': '原密码错误'})
        # 4.更新新密码
        try:
            request.user.set_password(new_password)
            request.user.save()
        except Exception as e:
            return http.JsonResponse({'code_s': RETCODE.DBERR, 'errmsg': '修改密码失败'})
        # 5.退出登陆,删除登陆信息
        logout(request)
        # 6.跳转到登陆页面
        response = http.JsonResponse({'code_s': RETCODE.OK, 'errmsg': '修改密码成功'})

        response.delete_cookie('username')

        return response
